

#ifndef	_LINKED_LIST_H_
#define	_LINKED_LIST_H_

#include "LinkedListNode.hpp"

template <typename T> class LinkedList{
public:
	LinkedListNode<T> *head;

	CALLCONV LinkedList(LinkedListNode<T> *firstNode = (LinkedListNode<T>*)0){
		head = firstNode;
	}
	
	CALLCONV bool initialize(LinkedListNode<T> *firstNode = (LinkedListNode<T>*)0){
		if(this == (LinkedList*)0) return false;
		head = firstNode;
		return true;
	}
	
	inline bool isEmpty(){
		if(this == (LinkedList*)0) return true;
		if(head == (LinkedListNode<T>*)0) return true;
		return false;
	}
	
	CALLCONV unsigned getSize(){
		if(this == (LinkedList*)0) return 0;
		unsigned size = 0;
		for(LinkedListNode<T> *temp = head;
			temp != (LinkedListNode<T>*)0;
			temp = temp->next) size++;
		return size;
	}
	
	CALLCONV unsigned indexOf(T element){
		if(this == (LinkedList*)0) return ~(unsigned)0;
		unsigned index = 0;
		for(LinkedListNode<T> *temp = head;
				temp != (LinkedListNode<T>*)0;
				temp = temp->next, index++)
			if(temp->key == element) return index;
		return ~(unsigned)0;
	}
	
	CALLCONV bool addNodeToFirst(LinkedListNode<T> *node){
		if(this == (LinkedList*)0) return false;
		if(node == (LinkedList<T>*)0) return false;
		node->next = head;
		head = node;
		return true;
	}
	
	CALLCONV bool addNodeToLast(LinkedListNode<T> *node){
		if(this == (LinkedList*)0) return false;
		if(node == (LinkedList<T>*)0) return false;
#if 0	// method 1
		if(head == (LinkedListNode<T>*)0){
			head = node;
		}else{
			LinkedListNode<T> *temp = head;
			while(temp->next != (LinkedListNode<T>*)0)
				temp = temp->next;
			temp->next = node;
		}
#else
		LinkedListNode<T> **temp = &head;
		while(*temp != (LinkedListNode<T>*)0)
			temp = &((*temp)->next);
		*temp = node;
#endif
		node->next = (LinkedListNode<T>*)0;
		return true;
	}
	
	CALLCONV bool removeFirstNode(LinkedListNode<T> **pnode){
		if(this == (LinkedList*)0) return false;
		if(head == (LinkedListNode<T>*)0) return false;
		if(pnode != (LinkedListNode<T>**)0) *pnode = head;
		head = head->next;
		return true;
	}
	
	CALLCONV bool removeLastNode(LinkedListNode<T> **pnode){
		if(this == (LinkedList*)0) return false;
		if(head == (LinkedListNode<T>*)0) return false;
#if 0	// method 1
		LinkedListNode<T> *temp0 = (LinkedListNode<T>*)0, *temp1 = head;
		while(temp1->next != (LinkedListNode<T>*)0){
			temp0 = temp1;
			temp1 = temp1->next;
		}
		if(pnode != (LinkedListNode<T>**)0) *pnode = temp1;
		if(head == temp1){
			head = (LinkedListNode<T>*)0;
		}
#else
		LinkedListNode<T> **temp = &head;
		while((*temp)->next != (LinkedListNode<T>*)0)
			temp = &((*temp)->next);
		if(pnode != (LinkedListNode<T>**)0) *pnode = *temp;
		*temp = (LinkedListNode<T>*)0;
#endif
		return true;
	}
	
	
}; // class LinkedList<T>

#endif	// _LINKED_LIST_H_
